package main

import (
	"bytes"
	"encoding/binary"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"os"
	"sync"
	"time"

	"husd.com/framework/v0/tcp"
)

var wg = sync.WaitGroup{}

func main() {

	//把指定文件的数据，发送给某一个tcp连接
	var count = flag.Int("n", 1, "发送多少次请求")

	if *count <= 0 {
		*count = 0
	}

	var t = flag.Int("t", 1000, "间隔多少毫秒，默认为1000")
	if *t <= 0 {
		*t = 1000
	}

	var ipPort = flag.String("p", "127.0.0.1:20000", "间隔多少毫秒，默认为1000")
	if *ipPort == "" {
		*ipPort = "127.0.0.1:20000"
	}

	var f = flag.String("f", "tcp cli test message", "间隔多少毫秒，默认为1000")
	if *f == "" {
		*f = "tcp cli test message"
	}

	var thread = flag.Int("thread", 1, "要启动多少个线程")

	flag.Parse()
	fmt.Println("len:", len(os.Args), "count is:", *count, " t is :", *t)

	var msg string
	_, err := os.Stat(*f)
	if err != nil && os.IsNotExist(err) {
		//直接发送文本的内容
		msg = *f
	} else {
		//读取文件内容
		bs, err1 := ioutil.ReadFile(*f)
		if err1 != nil {
			panic(err)
		}
		msg = string(bs)
	}
	for i := 0; i < *thread; i++ {
		wg.Add(1)
		go send2TcpServerWithLen(*ipPort, msg, *count, *t)
	}
	wg.Wait()
}

func send2TcpServer(ipPort string, bytes []byte, count int, t int) {

	defer wg.Done()
	conn, err := net.Dial("tcp", ipPort)
	if err != nil {
		fmt.Println("err :", err)
		return
	}
	defer conn.Close() // 关闭连接
	//send it
	//演示了怎么出现粘包，一次性发送很多的数据出去。
	for i := 0; i < count; i++ {
		_, err = conn.Write(bytes) // 发送数据
		if err != nil {
			return
		}
		//time.Sleep(time.Duration(t) * time.Millisecond)
	}
	buf := [512]byte{}
	n, err := conn.Read(buf[:])
	if err != nil {
		fmt.Println("recv failed, err:", err)
		return
	}
	fmt.Println(string(buf[:n]))
}

//TCP包的前4个字节表示包的长度。
func send2TcpServerWithLen(ipPort string, msg string, count int, t int) {

	defer wg.Done()
	conn, err := net.Dial("tcp", ipPort)
	if err != nil {
		fmt.Println("err :", err)
		return
	}
	defer conn.Close() // 关闭连接
	//send it
	//演示了怎么出现粘包，一次性发送很多的数据出去。
	data, err := encodeTcpMsgWithLen(msg)
	for i := 0; i < count; i++ {
		_, err = conn.Write(data) // 发送数据
		if err != nil {
			return
		}
		log.Println("tcp client send msg ", msg, " len :", tcp.BytesToInt(data[0:4]), " i=", i)
		if t > 0 {
			time.Sleep(time.Duration(t) * time.Millisecond)
		}
	}
}

func encodeTcpMsgWithLen(message string) ([]byte, error) {
	var length = int32(len(message))

	var pkg = new(bytes.Buffer)
	err := binary.Write(pkg, binary.BigEndian, length)
	if err != nil {
		return nil, err
	}

	err = binary.Write(pkg, binary.BigEndian, []byte(message))
	if err != nil {
		return nil, err
	}

	return pkg.Bytes(), nil
}
